import re
from typing import Optional
from common.enum.form_items_key import FormItemsKey
from common.enum.stock_risk_level_enum import RiskLevelEnum
from service.das import stock_base_info_das
from service.das.data_map_das import DataDictionaryDas
from service.strategy_engine_service import StrategyService
from .das.stock_monitor_das import StockDas
from .das.stock_day_das import StockDateDayDas
from .das.tushare_pool import getDayStock, getRealTime, get_single_stock_basic_info
from datetime import datetime, timedelta
from .das.sina_das import get_stock_info
from dto.stock_info_monitor import AntMonitorStockInfo


class StockMainService:
    def listSelfStock(self, sort_by="focus_level"):
        """
        获取所有股票列表，并根据不同的排序方式返回。
        :param sort_by: 排序方式，'focus_level' 或 'risk_level'
        :return: 股票列表
        """
        stock_das = StockDas()
        # 根据排序方式选择排序
        if sort_by == "risk_level":
            sorted_stocks = stock_das.get_stocks_by_risk_level()  # 按照风险等级排序
        elif sort_by == "focus_level":
            sorted_stocks = stock_das.get_stocks_by_focus_level()  # 按照关注等级排序
        return sorted_stocks

    def get_risk_level_description(self, risk_level: Optional[int]) -> str:
        """
        根据风险等级返回描述。
        :param risk_level: 风险等级（1-10）
        :return: 风险等级描述
        """
        return RiskLevelEnum.get_description(risk_level)

    def getAllStockListSample(self):
        stock_das = StockDas()
        stockList = stock_das.get_stocks()
        stockInfo = [f"{stock.stock_name} & {stock.stock_code}" for stock in stockList]
        return stockInfo

    def getAllStockList(self):
        stock_das = StockDas()
        stockList = stock_das.get_stocks()
        return stockList

    def saveMonitorStock(self, stockInfo: AntMonitorStockInfo):
        # 获取今天的日期
        today = datetime.today()
        # 获取一年前的日期
        dataMap = DataDictionaryDas()
        result = dataMap.get_item_by_form_enum(FormItemsKey.TUSHARE_INIT_DAY)
        days = 360  # 默认值
        if result and hasattr(result, "dict_value"):
            try:
                days = int(result.dict_value)
            except (ValueError, TypeError):
                AntLogger.info(f"警告: 无法将 {result.dict_value} 转换为整数，使用默认值 {days}")

        # 保存 Stock 数据
        stock_das = StockDas()
        stock = stock_das.get_stocks_byCode(stockInfo.stock_code)
        if stock:
            AntLogger.info(f"数据已存在,无需添加")
            return

        # 聚合出股票名称
        baseInfoService = stock_base_info_das.StockInfoService()
        baseInfo = baseInfoService.get_stock_info_by_code(stockInfo.stock_code)
        stockInfo.stock_name = baseInfo.name
        stockInfo.stock_plates = baseInfo.industry

        # 查询股票交易明细并且添加
        endTime = today.strftime("%Y%m%d")
        startTime = (today - timedelta(days=days)).strftime("%Y%m%d")
        df = getDayStock(stockInfo.stock_code, startTime, endTime)
        StockDateDayDas().add_stock(df)

        stock_das.add_stock(stockInfo)
        stockInfo = self.buildStockMonitorInfo(stockInfo)
        stock_das.update_stock_bycode(stockInfo)

    def updateMonitorStock(self, stockInfo: AntMonitorStockInfo):
        stock_das = StockDas()
        stockInfo = self.buildStockMonitorInfo(stockInfo)
        stock_das.update_stock_bycode(stockInfo)

    def deleteOneStock(self, stockCode):
        # 删除历史的 StockMonitor 的信息
        stock_das = StockDas()
        stock = stock_das.delete_bycode(stockCode)

        # 删除历史的 每日数据
        StockDateDayDas().delete_bycode(stockCode)

    def getByStockCode(self, stockCode):
        stock_das = StockDas()
        stock_record = stock_das.get_stocks_byCode(stockCode)
        return AntMonitorStockInfo(
            stock_code=stock_record.stock_code,
            stock_name=stock_record.stock_name,
            stock_focus_level=stock_record.stock_focus_level,
            stock_risk_level=stock_record.stock_risk_level,
            stock_current_number=stock_record.stock_current_number,
            stock_max_number=stock_record.stock_max_number,
            monitor_origin_price=stock_record.monitor_origin_price,
            monitor_current_price=stock_record.monitor_current_price,
            monitor_income_ratio=stock_record.monitor_income_ratio,
            monitor_income_money=stock_record.monitor_income_money,
            monitor_target_ratio=stock_record.monitor_target_ratio,
            monitor_stop_ratio=stock_record.monitor_stop_ratio,
            stock_status=stock_record.stock_status,
            stock_category=stock_record.stock_category,
            stock_tag=stock_record.stock_tag,
            next_advice=stock_record.stock_next_advice,
            month_up_day=stock_record.month_up_day,
            week_up_day=stock_record.week_up_day,
            other_info=stock_record.other_info,
        )

    def getRealTimeStock(self, stockCode):
        AntLogger.info(f"当前处理的股票{stockCode}")
        df = getRealTime(stockCode)
        AntLogger.info(f"获取到股票代码:{df}")
        result = [["stock_price", "type", "time"]]
        if df is not None:
            for index, row in df.iterrows():
                result.append(
                    [float(row["PRICE"]), "real", int(row["TIME"].replace(":", ""))]
                )

        return result

    def buildStockMonitorInfo(
        self, stockInfo: AntMonitorStockInfo
    ) -> AntMonitorStockInfo:
        # 异步进行策略计算
        strategyEngine = StrategyService()
        finalResult = strategyEngine.do_strategy_flow(stockInfo.stock_code)

        # 添加股票主数据
        stockInfo.monitor_current_price = finalResult.latest_price
        stock_current_number = stockInfo.stock_current_number or 0
        monitor_current_price = stockInfo.monitor_current_price or 0.0
        monitor_income_ratio = stockInfo.monitor_income_ratio or 0.0
        stockInfo.monitor_income_money = (
            (stock_current_number / 100)  # 将百倍数还原
            * monitor_current_price
            * (monitor_income_ratio / 100)  # 将百分比还原
        )

        stockInfo.stock_risk_level = finalResult.risk_level
        stockInfo.stock_focus_level = finalResult.focus_level
        return stockInfo
